package com.guyu.common.web.interceptor;

import com.alibaba.fastjson2.JSON;
import com.guyu.common.web.config.properties.GyWebProperties;
import com.guyu.common.web.filter.RepeatedlyRequestWrapper;
import com.guyu.common.web.util.GyServletUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.time.StopWatch;
import org.dromara.hutool.core.io.IoUtil;
import org.dromara.hutool.core.map.MapUtil;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import java.io.BufferedReader;
import java.util.Map;

/**
 * <p> web的调用时间统计拦截器 </p>
 *
 * @author tanyunpeng
 * @date 2024/8/8
 */
@Slf4j(topic = "request")
public class GuyuWebInvokeTimeInterceptor implements HandlerInterceptor {
    private final static ThreadLocal<StopWatch> KEY_CACHE = new ThreadLocal<>();
    private final GyWebProperties properties;

    public GuyuWebInvokeTimeInterceptor(GyWebProperties properties) {
        this.properties = properties;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if (!hasEnabled(request)) {
            return true;
        }
        //请求地址
        String url = request.getMethod() + " " + request.getRequestURI();
        // 打印请求参数
        String contentType = request.getContentType();
        if (GyServletUtils.isJsonRequest(contentType)) {
            String jsonParam = "";
            if (request instanceof RepeatedlyRequestWrapper) {
                BufferedReader reader = request.getReader();
                jsonParam = IoUtil.read(reader);
            }
            log.info("[GUYU]开始请求 => URL[{}],请求头[{}],参数:[{}]", url, contentType, jsonParam);
        } else {
            Map<String, String[]> parameterMap = request.getParameterMap();
            if (MapUtil.isNotEmpty(parameterMap)) {
                String parameters = JSON.toJSONString(parameterMap);
                log.info("[GUYU]开始请求 => URL[{}],请求头[{}],参数:[{}]", url, contentType, parameters);
            } else {
                log.info("[GUYU]开始请求 => URL[{}],请求头[{}],无参数", url, contentType);
            }
        }

        StopWatch stopWatch = new StopWatch();
        KEY_CACHE.set(stopWatch);
        stopWatch.start();
        return true;
    }

    @Override
    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
        if (!hasEnabled(request)) {
            return;
        }
        StopWatch stopWatch = KEY_CACHE.get();
        stopWatch.stop();
        log.info("[GUYU]结束请求 => URL[{}],耗时:[{}]毫秒", request.getMethod() + " " + request.getRequestURI(), stopWatch.getTime());
        KEY_CACHE.remove();
    }

    /**
     * 是否满足打印日志
     */
    boolean hasEnabled(HttpServletRequest request) {
        GyWebProperties.Request requestLog = properties.getRequestLog();
        if (!requestLog.getEnabled()) {
            return false;
        }
        // 排除请求
        return !requestLog.getExcludeUrl().contains(request.getRequestURI());
    }


}
